home *** CD-ROM | disk | FTP | other *** search
- #include <unistd.h>
- #include <grp.h>
- #include <sys/stat.h>
- #include "../xconf/xconf.h"
- #include "../paths.h"
- #include "internal.h"
- #include "userconf.h"
- #include "userconf.m"
-
- #define ETC_GTMP "/etc/gtmp"
-
- static USERCONF_HELP_FILE help_groups("groups");
- static CONFIG_FILE f_group (ETC_GROUP,help_groups,CONFIGF_MANAGED
- ,"root","root",0644);
-
- PUBLIC GROUPS::GROUPS()
- {
- struct group *p;
- while ((p=getgrent())!=NULL){
- add (new GROUP(p));
- }
- endgrent();
- rstmodified();
- }
-
- PUBLIC GROUPS::~GROUPS()
- {
- }
- /*
- Get one GROUP specification of the table or NULL
- */
- PUBLIC GROUP *GROUPS::getitem(int no)
- {
- return (GROUP*)ARRAY::getitem(no);
- }
- /*
- Return the GROUP specification from its name.
- Return NULL if not found.
- */
- PUBLIC GROUP *GROUPS::getitem(const char *name)
- {
- GROUP *ret = NULL;
- int nbg = getnb();
- for (int i=0; i<nbg; i++){
- GROUP *grp = getitem(i);
- if (strcmp(grp->getname(),name)==0){
- ret = grp;
- break;
- }
- }
- return ret;
- }
- /*
- Return the gid of a group from its name.
- Return -1 if there is no group with this name.
- */
- PUBLIC int GROUPS::getgid(const char *name)
- {
- GROUP *grp = getitem(name);
- return grp == NULL ? -1 : grp->getgid();
- }
- /*
- Write the /etc/group file with proper locking
- */
- PUBLIC int GROUPS::write()
- {
- int ret = -1;
- FILE *fout = f_group.fopen (ETC_GTMP,"w");
- if (fout != NULL){
- int nbu = getnb();
- for (int i=0; i<nbu; i++){
- getitem(i)->write(fout);
- }
- fclose(fout);
- unlink(ETC_GROUP ".OLD");
- link(ETC_GROUP, ETC_GROUP ".OLD");
- unlink(ETC_GROUP);
- link(ETC_GTMP, ETC_GROUP);
- unlink(ETC_GTMP);
- chmod(ETC_GROUP, 0644);
- ret = 0;
- }
- return ret;
- }
- /*
- Return the name of the group to use when creating new user (default)
- */
- PUBLIC const char *GROUPS::getdefault()
- {
- /* #Specification: userconf / groups / default for creation
- The default group is "users". If this group does not
- exist. then the group "group" is used. If none of those
- group exist, then no default group is proposed to
- the user.
- */
- /* #todo: userconf / groups and users / default for creation
- It is not clear if a default setup should exist such
- as /etc/default/useradd and could be edited by userconf.
-
- Currently, we assumed that the default user group is 1.
- */
- const char *ret = NULL;
- if (getitem("users")!=NULL){
- ret = "users";
- }else if (getitem("group")!=NULL){
- ret = "group";
- }
- return ret;
- }
-
- /*
- Get one GROUP specification of the table or NULL from his GID
- */
- PUBLIC GROUP *GROUPS::getfromgid(int gid)
- {
- GROUP *ret = NULL;
- int nbg = getnb();
- for (int i=0; i<nbg; i++){
- GROUP *grp = getitem(i);
- if (grp->getgid() == gid){
- ret = grp;
- break;
- }
- }
- return ret;
- }
-
- /*
- Allocate an unused group ID.
- */
- PUBLIC int GROUPS::getnew()
- {
- /* #Specification: userconf / groups / group ID allocation
- When creating a new group, the group ID may be left
- blank. An unused group ID will be allocated. The first
- one unused will be allocated.
-
- We assume that a maximum of 1000 group may be configured.
- */
- for (int i=1; i<1000; i++){
- if (getfromgid(i)==NULL) break;
- }
- return i;
- }
-
- static int cmpbyname (ARRAY_OBJ *o1, ARRAY_OBJ *o2)
- {
- GROUP *g1 = (GROUP*) o1;
- GROUP *g2 = (GROUP*) o2;
- return strcmp(g1->getname(),g2->getname());
- }
- /*
- Sort the array of group by name
- */
- PUBLIC void GROUPS::sortbyname()
- {
- sort (cmpbyname);
- }
- /*
- General edition (addition/deletion/correction) of /etc/group
- */
-
- PUBLIC int GROUPS::edit()
- {
- int ret = -1;
- int choice = 0;
- USERS users;
- sortbyname();
- while (1){
- int nbg = getnb();
- const char **menuopt = (const char**)malloc_err((nbg*2+1)
- *sizeof(char*));
- const char **ptsort = menuopt;
- for (int i=0; i<nbg; i++){
- *ptsort++ = getitem(i)->getname();
- *ptsort++ = " ";
- }
- *ptsort = NULL;
- MENU_STATUS code = xconf_menu (
- MSG_U(T_GROUPS,"User groups")
- ,MSG_U(I_GROUPS,"You can edit, add, or delete groups")
- ,help_groups
- ,NULL
- ,NULL
- ,NULL
- ,MSG_U(I_TOADD,"to add a new definition")
- ,menuopt,choice);
- if (code == MENU_ESCAPE || code == MENU_QUIT){
- break;
- }else{
- GROUP *grp = getitem(menuopt[choice*2]);
- if (code == MENU_OK){
- int status = grp->edit(users,*this);
- if (status != -1){
- if (status == 1) remove_del (grp);
- write();
- ret = 0;
- }
- }else if (perm_rootaccess(
- MSG_R(P_GROUPDB))){
- if (code == MENU_ADD){
- GROUP *ngrp = new GROUP;
- if (ngrp->edit(users,*this)==0){
- add (ngrp);
- write ();
- ret = 0;
- }else{
- delete ngrp;
- }
- }
- }
- }
- }
- return ret;
- }
-
- void groups_edit()
- {
- GROUPS groups;
- groups.edit();
- }
-
- /*
- Get the ID of a group. Create it if it does not exist.
- Return -1 if it was not created.
- */
- int group_getcreate (const char *name, const char *reason)
- {
- GROUPS groups;
- int gid = groups.getgid (name);
- if (gid == -1){
- char buf[1000];
- sprintf (buf
- ,MSG_U(I_GROUPCREATE
- ,"The group %s does not exist on your\n"
- "system. It is needed to %s\n"
- "\n"
- "Do you want to create it ? (why not)")
- ,name,reason);
-
- if (xconf_yesno(MSG_U(Q_GROUPCREATE,"Mandatory group creation")
- ,buf,help_nil) == MENU_YES){
- gid = groups.getnew();
- GROUP *grp = new GROUP (name,"*",gid,NULL);
- groups.add (grp);
- groups.write();
- }
- }
- return gid;
- }
-
-
- #ifdef TEST
-
- int main (int argc, char *argv[])
- {
- groups_edit();
- }
-
- #endif
-
-
-